﻿#region Summary

// 
// Owner : JackieHan 
// 
// Solution : Erp 
// 
// Project : Jackie.Utility.BvConversion
// 
// File : BusinessViewConfig.cs
// 
// CopyRight : Copyright © 2010-2011 Skomart Corporation, All Rights Reserved 
// 
// Summary : Business Object <=>View Object 配置集合
// 
// History : 
//			2012-07-13 14:54:05	    Create 
// 

#endregion

#region Using

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

#endregion

namespace Jackie.Utility.BvConversion
{
    ///<summary>
    ///Business Object <=>View Object 配置类集合
    ///</summary>
    public class BusinessViewConfigCollection
    {
        private IDictionary<string, IDictionary<string, ObjectConversionConfig>> configs { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public BusinessViewConfigCollection()
        {
            configs = new Dictionary<string, IDictionary<string, ObjectConversionConfig>>();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="businessTypeName"></param>
        /// <returns></returns>
        public bool ContainsKey(string businessTypeName)
        {
            return configs.ContainsKey(businessTypeName);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="businessTypeName"></param>
        public IDictionary<string, ObjectConversionConfig> this[string businessTypeName]
        {
            get { return configs[businessTypeName]; }
            set { configs[businessTypeName] = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public int Count
        {
            get { return configs.Count; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TB"></typeparam>
        /// <typeparam name="TV"></typeparam>
        public void RegisterConversionDefine<TB, TV>()
            where TB : class
            where TV : class
        {
            RegisterConversionDefine<TB, TV>(ps => { });
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TB"></typeparam>
        /// <typeparam name="TV"></typeparam>
        /// <param name="customizePropertySet"></param>
        public void RegisterConversionDefine<TB, TV>(Action<IPropertyDefineSet<TB, TV>> customizePropertySet)
            where TB : class
            where TV : class
        {
            var businessType = typeof(TB);
            var viewType = typeof(TV);

            var businessTypeName = businessType.FullName;
            var viewTypeName = viewType.FullName;

            if (string.IsNullOrEmpty(businessTypeName))
                throw new Exception("未知错误!");

            if (string.IsNullOrEmpty(viewTypeName))
                throw new Exception("未知错误!");

            if (!configs.ContainsKey(businessTypeName))
                configs.Add(businessTypeName, new Dictionary<string, ObjectConversionConfig>());

            if (!configs[businessTypeName].ContainsKey(viewTypeName))
                configs[businessTypeName].Add(viewTypeName, new ObjectConversionConfig(businessTypeName, viewTypeName));

            var businessViewConfig = configs[businessTypeName][viewTypeName];

            RegisterDefaultPropertyDefine(businessType, viewType, businessViewConfig);
            customizePropertySet(new DefaultPropertyDefineSet<TB, TV>(businessViewConfig));
        }

        /// <summary>
        /// 注册TB,TV之间的转换关系
        /// </summary>
        public void RegisterDefaultPropertyDefine(Type businessType, Type viewType, ObjectConversionConfig businessViewConfig)
        {
            var viewTypeProperties = viewType.GetProperties();
            foreach (var viewProperty in viewTypeProperties)
            {
                var businessProperty = businessType.GetProperty(viewProperty.Name);
                if (businessProperty != null)
                {
                    var propertyConf = new PropertyConfig()
                    {
                        BusinessProperty = businessProperty.Name,
                        ViewProperty = viewProperty.Name,
                    };
                    if ((viewProperty.Name.Equals("Id")) || (viewProperty.Name.Equals("id")) ||
                        (viewProperty.Name.Equals("ID")))
                    {
                        propertyConf.IsKey = true;
                    }
                    businessViewConfig.PropertyConfigs.Add(propertyConf);
                }
            }
        }
    }
}